
// Copyright (c) WanSheng Intelligent Corp. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.


#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "wa_edge_types.h"
#include "wa_alarm.h"
#include "cJSON.h"
#include "logs.h"


void wa_init_event(wa_event_t* event, event_id_t event_id,
        severity_t severity,
        object_type_t target_type,
        const char * target_id,
        const char * title,
        const char * content)
{
    memset(event, 0, sizeof(*event));
    event->event_id = event_id;
    event->severity = severity;
    event->obj_type = target_type;
    time(&event->event_time);
    strncpy(event->obj_id, target_id, sizeof(event->obj_id)-1);
    if(title) strncpy(event->title, title, sizeof(event->title)-1);
    if(content) strncpy(event->content, content, sizeof(event->content)-1);
}

static void  set_event_JSON(cJSON* j_event,
        unsigned int event_id,
        const char * title,
        object_type_t target_type,
        const char * target_id,
        const char * content,
        time_t start,
        severity_t severity)
{
    cJSON_AddNumberToObject(j_event, "eventid", event_id);
    cJSON_AddStringToObject(j_event, "title", title);
    cJSON_AddStringToObject(j_event, "targetid", target_id);
    cJSON_AddNumberToObject(j_event, "targettype", target_type);
    cJSON_AddStringToObject(j_event, "content", content);
    cJSON_AddNumberToObject(j_event, "set_t", start);
    cJSON_AddNumberToObject(j_event, "severity", severity);
}    



void single_event_to_JSON(wa_event_t* event, cJSON * elem)
{
    set_event_JSON(elem, 
        event->event_id,
        event->title,
        event->obj_type,
        event->obj_id,
        event->content,
        event->event_time,
        event->severity);
}



char* serialize_single_event(wa_event_t* event)
{
    cJSON * root = cJSON_CreateObject();
    single_event_to_JSON(event, root);
    char * text = cJSON_Print(root);
    cJSON_Delete(root);
    return text;
}



bool parse_single_event(cJSON * item, wa_event_t * event)
{
    if(item->type != cJSON_Object)
        return false;

    memset(event, 0, sizeof(*event));
    
    cJSON * e = cJSON_GetObjectItem(item, "targettype");
    if(!cJSON_IsNumber(e))
        return false;
    event->obj_type = e->valueint;    

    e = cJSON_GetObjectItem(item, "targetid");
    if(e == NULL || e->type != cJSON_String)
        return false;
    strncpy(event->obj_id, e->valuestring, sizeof(event->obj_id)-1);

    e = cJSON_GetObjectItem(item, "eventid");
    if(e == NULL || e->type != cJSON_Number)
        return false;
    event->event_id = e->valuedouble;

    // end of mandatory fields
    e = cJSON_GetObjectItem(item, "title");
    if(e != NULL && e->type == cJSON_String)
        strncpy(event->title, e->valuestring, sizeof(event->title)-1);


    e = cJSON_GetObjectItem(item, "severity");
    if(e != NULL && e->type == cJSON_Number)
        event->severity = e->valuedouble;


    e = cJSON_GetObjectItem(item, "set_t");
    if(e != NULL && e->type == cJSON_Number)
        event->event_time = e->valuedouble;


    e = cJSON_GetObjectItem(item, "content");
    if(e != NULL && e->type == cJSON_String)
        strncpy(event->content, e->valuestring, sizeof(event->content)-1);


    return true;
}


int parse_event_payload_A(char * payload, int len, wa_event_t ** events_out)
{
    int cnt = 0;
    wa_event_t * events = NULL;
    cJSON * root = cJSON_ParseWithLength(payload, len);
    if(root == NULL)
        return false;

    if(root->type == cJSON_Object)
    {
        events = (wa_event_t*) malloc(sizeof(wa_event_t));
        if(parse_single_event(root, events))
            cnt = 1;

        goto end;
    }
    else if(root->type == cJSON_Array)
    {
        cJSON * elem;
        events = (wa_event_t*) malloc(sizeof(wa_event_t)*cJSON_GetArraySize(root));
        if(events == NULL)
        {
            goto end;
        }
        cJSON_ArrayForEach(elem, root)
        {
            if(parse_single_event(elem, events+cnt))
            {
                cnt ++;
            }
        }
    }
    else
    {
        WARNING2("invalid event payload");
    }
end:
    cJSON_Delete(root);
    *events_out = events;
    return cnt;
}


